package com.yuyue.springFramework.note08.entity.lifeCycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

import java.lang.reflect.Constructor;

@Component
//@Lazy
/**
 * Spring后处理器参与生命周期各阶段总览
 * 实现的后处理器接口在下面各方法中均有对应
 */
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor,
        SmartInstantiationAwareBeanPostProcessor,
        MergedBeanDefinitionPostProcessor,
        DestructionAwareBeanPostProcessor,
        BeanNameAware,
        BeanClassLoaderAware,
        BeanFactoryAware,
        SmartInitializingSingleton
        {

    @Override
    public void setBeanName(String name) {
        System.out.println("1-注入bean的名称");
        System.out.println("[ BeanNameAware#setBeanName 方法 ]");
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("2-注入类加载器BeanClassLoader");
        System.out.println("[ BeanClassLoaderAware#setBeanClassLoader 方法 ]");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("3-注入Bean工厂BeanFactory");
        System.out.println("[ BeanFactoryAware#setBeanClassLoader 方法 ]");
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if("lifeCycleBean".equals(beanName)) {
            System.out.println("4-实例化之前执行，这里返回非空对象会跳过spring内部实例化目标bean的过程");
            System.out.println("[ InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法 ]");
        }
        return null;
    }

    @Override
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
            throws BeansException {
        if("lifeCycleBean".equals(beanName)){
            System.out.println("5-确定候选构造器");
            System.out.println("[ SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors 方法 ]");
        }
        return null;
    }

    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        if("lifeCycleBean".equals(beanName)){
            System.out.println("6-合并后的BeanDefinition依赖载入缓存");
            System.out.println("[ MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 方法 ]");
        }
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if("lifeCycleBean".equals(beanName)) {
            System.out.println("7-实例化之后，属性填充之前执行。正常的实现应该返回true。" +
                    "返回false还将阻止在此 bean 实例上后续调用任何 InstantiationAwareBeanPostProcessor 实例。" +
                    "目前后续调用为依赖注入" +
                    "");
            System.out.println("[ InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 方法 ]");
        }
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if("lifeCycleBean".equals(beanName)) {
            System.out.println("8-依赖注入阶段执行，如 @Autowired、@Value、@Resource");
            System.out.println("[ InstantiationAwareBeanPostProcessor#postProcessProperties 方法 ]");
        }
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if("lifeCycleBean".equals(beanName)) {
            System.out.println("9-初始化之前执行，这里返回的对象会替换原本的 bean，如 @PostConstruct");
            System.out.println("[ BeanPostProcessor#postProcessBeforeInitialization 方法 ]");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if("lifeCycleBean".equals(beanName)) {
            System.out.println("10-初始化之后执行，这里返回的对象会替换原本的 bean，如代理增强");
            System.out.println("[ BeanPostProcessor#postProcessAfterInitialization 方法 ]");
        }
        return bean;
    }

    @Override
    public void afterSingletonsInstantiated() {
        System.out.println("11-所有单例Bean实例化完成");
        System.out.println("[ SmartInitializingSingleton#afterSingletonsInstantiated 方法 ]");
    }

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        if("lifeCycleBean".equals(beanName)){
            System.out.println("12-销毁之前执行，如@PreDestroy");
            System.out.println("[ DestructionAwareBeanPostProcessor#postProcessBeforeDestruction 方法 ]");
        }
    }
}
